package cfca.seal.web.interceptor;

import cfca.seal.bean.AdminUser;
import cfca.seal.exception.CodeException;
import cfca.seal.system.Env;
import cfca.seal.util.StringUtil;
import cfca.seal.web.system.SessionManager;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

public class CommonInterceptor
  implements HandlerInterceptor
{
  private String[] excludeUrls;
  private String loginUrl;
  private String processUrl;
  private String returnUrl;

  public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object obj, Exception e)
    throws Exception
  {
  }

  public void postHandle(HttpServletRequest req, HttpServletResponse res, Object obj, ModelAndView model)
    throws Exception
  {
  }

  public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj)
    throws Exception
  {
    req.getSession().setAttribute("root", req.getContextPath());

    req.getSession().setAttribute("language", req.getLocale().getLanguage());
    boolean isOperation = false;
    String url = req.getRequestURI();
    String[] pathArr = url.split("\\.do")[0].split("/");
    String method = pathArr[(pathArr.length - 1)];
    if (method.startsWith("o_"))
    {
      isOperation = true;
    }
    String servletPath = req.getServletPath();

    if (this.excludeUrls != null) {
      for (String exc : this.excludeUrls) {
        if (exc.equals(servletPath)) {
          return true;
        }
      }
    }
    String[] blackCharArr = Env.specialChar.split(" ");
    String referer = req.getHeader("Referer");
    if ((referer != null) && (referer.indexOf(req.getContextPath()) < 0)) {
      CodeException ce = new CodeException("C0002", "可能存在跨站点请求风险");
      throw ce;
    }

    AdminUser manager = SessionManager.getManager(req);
    if (null != manager)
    {
      Enumeration argsEn = req.getParameterNames();
      while (argsEn.hasMoreElements()) {
        String argV = req.getParameter((String)argsEn.nextElement());
        if (existBlackChar(argV, blackCharArr)) {
          CodeException ce = new CodeException("C0001", "包含敏感字符:" + Env.specialChar);
          throw ce;
        }
      }
    } else {
      res.sendRedirect(req.getContextPath() + "/logout.do");
      return false;
    }

    return true;
  }

  private boolean existBlackChar(String argV, String[] blackCharArr) {
    for (String blackChar : blackCharArr) {
      if ((StringUtil.isNotEmpty(blackChar)) && (argV.indexOf(blackChar) > -1)) {
        return true;
      }
      if (sqlValidate(argV)) {
        return true;
      }
    }
    return false;
  }

  public static boolean sqlValidate(String str)
  {
    str = str.toLowerCase();
    String badStr = "insert |select |delete |update |drop |union ";
    String[] badStrs = badStr.split("\\|");
    for (int i = 0; i < badStrs.length; i++) {
      if (str.indexOf(badStrs[i]) >= 0) {
        return true;
      }
    }
    return false;
  }

  public String[] getExcludeUrls() {
    return this.excludeUrls;
  }

  public void setExcludeUrls(String[] excludeUrls) {
    this.excludeUrls = excludeUrls;
  }

  public String getLoginUrl() {
    return this.loginUrl;
  }

  public void setLoginUrl(String loginUrl) {
    this.loginUrl = loginUrl;
  }

  public String getProcessUrl() {
    return this.processUrl;
  }

  public void setProcessUrl(String processUrl) {
    this.processUrl = processUrl;
  }

  public String getReturnUrl() {
    return this.returnUrl;
  }

  public void setReturnUrl(String returnUrl) {
    this.returnUrl = returnUrl;
  }
}